package com.to8to.kitt.esb.http;

import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpResponseStatus;

import org.apache.thrift.protocol.TMessage;
import org.apache.thrift.protocol.TMessageMeta;
import org.apache.thrift.protocol.TMessageType;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.to8to.commons.json.JSONObject;
import com.to8to.kitt.ThriftMessage;
import com.to8to.kitt.esb.BusChannelHandler;
import com.to8to.kitt.utils.LogUtils;


@Sharable
public class Thrift2HttpHandler extends ChannelHandlerAdapter {
	
	public static Logger logger = LoggerFactory.getLogger(Thrift2HttpHandler.class);  
	
	ObjectMapper mapper = new ObjectMapper();
	
	Gson gson = new Gson();
	
	@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) 
    {
    	ThriftMessage inMsg = (ThriftMessage)msg;
    	try {
    		int seqid = inMsg.getSeqid();
    		
    		TMessage head = inMsg.getHead();
    		
    		TMessageMeta meta = inMsg.getMeta();
    		
    		LogUtils.openTag(meta.tag);
    		
    		logger.debug("===> 收到下游回复, 消息通道:{}, 对方地址:{}, 消息头:{}", ctx.channel(), ctx.channel().remoteAddress(), head);
    		
    		logger.trace("======> 收到消息体: \n" + inMsg);
    		
    		String msgKey = BusChannelHandler.genKey(inMsg.getHead().name, seqid);
    		
    		HttpBusMessageState status =  HttpBusServer.getAndRemoveState(msgKey);
    		
    		if(status != null)
    		{
    			status.recordRecvFromDownTime();
    			
    			ChannelHandlerContext upctx = status.getUpctx();
	    		
	        	String txt = "";//gson.toJson(inMsg);
	        	
	        	HttpResponseStatus httpStatus = HttpResponseStatus.OK;
	        	
	        	if(head.type == TMessageType.REPLY)
	        	{
	        		txt = gson.toJson(inMsg.getBody());
	        		if(txt.trim().equals("{}"))
	        			txt = "{\"success\":null}";
	        	}
	        	else if(head.type == TMessageType.EXCEPTION)
	        	{
	        		txt = gson.toJson(inMsg.getException());
//	        		txt = JSONObject.escape(txt);
//	        		txt = "{\"fail\":\""+ txt + "\"}";
	        		httpStatus = HttpResponseStatus.INTERNAL_SERVER_ERROR;
	        	}
	        	
	        	ChannelFutureListener l = new HttpSCFutureListener(status);
	        	
	        	status.recordStartSendClientTime();
	        	
	        	Http2ThriftHandler.sendResponse(upctx, httpStatus, txt, l);
    		}
    		else 
    		{
    			logger.error("消息key:[{}]查找失败! 消息头: {}", msgKey, inMsg.getHead());
//    			HttpBusMessageState ssss =  HttpBusServer.getAndRemoveState(msgKey);
    			
//    			Http2ThriftHandler.sendResponse(upctx, HttpResponseStatus.INTERNAL_SERVER_ERROR, "消息key查找失败! 消息头: " + inMsg.getHead(), l);
    		}
        	
        	LogUtils.removeTag();
        } 
    	catch(Exception e)
    	{
    		logger.error(LogUtils.logStackTrace(e));
    	}
    }
}
